#include "vec3f.h"

//
// toZero
//
void vec3f::toZero() {
	this->x = 0.0f;
	this->y = 0.0f;
	this->z = 0.0f;
};

//
//	Inverse
//
vec3f vec3f::inverse() const {
	return vec3f(-x, -y, -z);
}

//
//	LengthSquared - useful if we want to avoid expensive sqrt()
//
float vec3f::lengthSquared() const {
	return (x * x) + (y * y) + (z * z);
};

//
//	Length - Vector magnitude
//
float vec3f::length() const {
	if(lengthSquared() == 0) { return 0; }
	return sqrt(lengthSquared());
};

//
//	Normalize
//
void vec3f::normalize() {
	float l = length();
	if(l != 0.0f) {
		l = 1.0f / l;
		x = x * l;
		y = y * l;
		z = z * l;
	}
};



//
//	Dot product
//
static vec3f dot(const vec3f &a, const vec3f &b) {
	return vec3f((a.x + b.x), (a.y + b.y), (a.z + b.z));
};

//
//	Cross Product
//
static vec3f cross(const vec3f &a, const vec3f &b) {
	return vec3f((a.y*b.z) - (a.z*b.y), (a.z*b.x) - (a.x*b.z), (a.x*b.y) - (a.y*b.x));
};



//
//	Inverse operator
//
inline vec3f vec3f::operator-() const {
	return vec3f(-x, -y, -z);
};

//
//	Comparison operator
//
inline bool vec3f::operator==(const vec3f &src) const {
	return ((x == src.x) && (y == src.y) && (z == src.z)) ? true : false;
};
inline bool vec3f::operator!=(const vec3f &src) const {
	return ((x == src.x) && (y == src.y) && (z == src.z)) ? false : true;
};

//
//	Vector Addition
//
inline vec3f vec3f::operator+(const vec3f &src) const {
	return vec3f( (this->x + src.x), (this->y + src.y), (this->z + src.z) );
};

//
//	Vector Subtraction
//
inline vec3f vec3f::operator-(const vec3f &src) const {
	return vec3f( (this->x - src.x), (this->y - src.y), (this->z - src.z) );
};

//
//	Vector multiplication
//
inline vec3f vec3f::operator*(const vec3f &src) const {
	return vec3f((x * src.x), (y * src.y), (z * src.z));
};

//
//	Vector division
//
inline vec3f vec3f::operator/(const vec3f &src) const {
	return vec3f((x / src.x), (y / src.y), (z / src.z));
};

//
//	Vector add-equals +=
//
inline void vec3f::operator+=(const vec3f &src) {
	this->x += src.x;
	this->y += src.y;
	this->z += src.z;
};

//
//	Vector subtract-equals -=
//
inline void vec3f::operator-=(const vec3f &src) {
	this->x -= src.x;
	this->y -= src.y;
	this->z -= src.z;
};

//
//	Vector multiply-equals *=
//
inline void vec3f::operator*=(const vec3f &src) {
	this->x *= src.x;
	this->y *= src.y;
	this->z *= src.z;
};

//
//	Vector divide-equals
//
inline void vec3f::operator/=(const vec3f &src) {
	this->x /= src.x;
	this->y /= src.y;
	this->z /= src.z;
};





//
//	Scalar addition
//
inline vec3f vec3f::operator+(const float a) const {
	return vec3f((x + a), (y + a), (z + a));
};

//
//	Scalar subtraction
//
inline vec3f vec3f::operator-(const float a) const {
	return vec3f((x - a), (y - a), (z - a));
};

//
//	Scalar multiplication
//
inline vec3f vec3f::operator*(const float a) const {
	return vec3f((x * a), (y * a), (z * a));
};

//
//	Scalar division
//
inline vec3f vec3f::operator/(const float a) const {
	return vec3f((x / a), (y / a), (z / a));
};